package com.springboot.config;

import com.alibaba.fastjson.JSON;
import com.springboot.constants.SercurityConstants;
import com.springboot.core.security.FilterStatic;
import com.springboot.core.security.MAuthenticationProvider;
import com.springboot.core.security.MyFilterSecurityInterceptor;
import com.springboot.sql.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.context.SecurityContextImpl;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * On 2017/2/23 0023.
 * spring-security 配置
 */
@Configuration
@EnableWebSecurity
@AutoConfigureAfter(MyBatisMapperScannerConfig.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 自定义认证
     */
    private final MAuthenticationProvider provider;
    /**
     * 自定义动态权限过滤器
     */
    private final MyFilterSecurityInterceptor myFilterSecurityInterceptor;
    private final FilterStatic filterStatic;
    private final IMenuService iMenuService;

    @Autowired
    public WebSecurityConfig(MAuthenticationProvider provider, MyFilterSecurityInterceptor myFilterSecurityInterceptor, FilterStatic filterStatic, IMenuService iMenuService) {
        this.provider = provider;
        this.myFilterSecurityInterceptor = myFilterSecurityInterceptor;
        this.filterStatic = filterStatic;
        this.iMenuService = iMenuService;
    }

    /**
     *  自定义过滤规则及其安全配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .headers().frameOptions().disable().and()//允许内嵌Iframe
                .csrf().disable().cors().disable().authorizeRequests()//关闭CSRF
                .anyRequest().fullyAuthenticated()
              .and()
                .formLogin()
                .usernameParameter("username")
                .passwordParameter("password")
                .loginProcessingUrl("/login")
                .successHandler((httpServletRequest, httpServletResponse, authentication) -> {
                    httpServletResponse.setCharacterEncoding("UTF-8");
                    Map<String,Object> result = new HashMap<>();
                    result.put("user",authentication.getPrincipal());
                    result.put("info","success");
                    result.put("code","0");
                    //放入权限信息
                    List<String> authories=authentication.getAuthorities().stream().map(m->
                            m.getAuthority()
                                    //截取ROLE_前缀
                                    .substring(m.getAuthority().indexOf(SercurityConstants.prefix)+SercurityConstants.prefix.length()))
                            .collect(Collectors.toList());
                    result.put("authories",authories);
                    result.put("menus",iMenuService.getMenuByRoles(authories));
                    httpServletResponse.addHeader("Access-Control-Allow-Origin",httpServletRequest.getHeader("Origin"));
                    httpServletResponse.setContentType("application/json; charset=utf-8");
                    CorsConfig.recordCors(httpServletRequest,httpServletResponse);
                    resloveOut(httpServletResponse,result);
                })
                .failureHandler((httpServletRequest, httpServletResponse, authentication) -> {
                    httpServletResponse.setCharacterEncoding("UTF-8");
                    Map<String,Object> result = new HashMap<>();
                    result.put("info","error");
                    result.put("code","100");
                    httpServletResponse.addHeader("Access-Control-Allow-Origin",httpServletRequest.getHeader("Origin"));
                    httpServletResponse.setContentType("application/json; charset=utf-8");
                    CorsConfig.recordCors(httpServletRequest,httpServletResponse);
                    resloveOut(httpServletResponse,result);
                })
                .permitAll()
        .and()
        .logout()
                .logoutSuccessUrl("/login.html")
                .logoutUrl("/logout")
                .permitAll();
//        .and().addFilterBefore(new CorsConfig.MCorsFilter(),FilterSecurityInterceptor.class);
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(provider);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //静态文静过滤
        String []filter=filterStatic.getStaticFilters().toArray(new String[0]);
        web.ignoring().antMatchers(filter);
    }


    private void resloveOut (HttpServletResponse httpServletResponse,Object result){
        PrintWriter out = null;
        try {
            out = httpServletResponse.getWriter();
            out.append(JSON.toJSONString(result));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}
